package jc.service.http;

import com.sun.xml.internal.ws.util.StringUtils;
import org.apache.http.*;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.ssl.TrustStrategy;
import org.apache.http.util.EntityUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;

import javax.net.ssl.SSLContext;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by ��� on 2015/7/17.
 */

@Service("httpGetClient")
public class HttpGetClient {

    CloseableHttpClient httpclient;
    ResponseHandler<String> responseStringHandler;
    ResponseHandler<Map<String, Object>> responseByteHandler;



    public HttpGetClient() {

        //ʹ��֧��sslȡ��Ĭ�ϵ�httpclient
        //this.httpclient = HttpClients.createDefault();

        //Ŀǰ��ʹ��
        this.responseStringHandler  = new ResponseHandler<String>() {

            @Override
            public String handleResponse(
                    final HttpResponse response) throws ClientProtocolException, IOException {
                int status = response.getStatusLine().getStatusCode();
                if (status >= 200 && status < 300) {
                    HttpEntity entity = response.getEntity();
                    return entity != null ? EntityUtils.toString(entity) : null;
                } else {
                    throw new ClientProtocolException("Unexpected response status: " + status);
                }
            }

        };

        this.responseByteHandler = new ResponseHandler<Map<String, Object>>() {

            @Override
            public Map<String, Object> handleResponse(
                    HttpResponse response) throws ClientProtocolException, IOException {
                HttpEntity entity = response.getEntity();
                HeaderElement[] a = entity.getContentType().getElements();

                String contentType = null;
                String type = null;
                String charset = null;

                Header contentTypeHeader = response.getEntity().getContentType();

                if (contentTypeHeader != null){

                    contentType = contentTypeHeader.getValue();

                    HeaderElement[] contentTypeElements = contentTypeHeader.getElements();
                    if (contentTypeElements[0] != null){
                        type = contentTypeHeader.getElements()[0].getName();

                        NameValuePair charsetPair = contentTypeElements[0].getParameterByName("charset");
                        if (charsetPair != null) {
                            charset = charsetPair.getValue();
                        }


                    }


                }




                if (entity != null) {

                    Map<String, Object> map = new HashMap();
                    map.put("contentType", contentType);  //  text/html; charset=GB2312
                    map.put("byte", EntityUtils.toByteArray(entity));
                    map.put("charset", charset);  // charset=GB2312
                    map.put("type", type);   //  text/html
                    return map;
                } else {
                    return null;
                }
            }
        };

        //����һ��֧��https��httpclient
        try {
            SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
                //��������
                public boolean isTrusted(X509Certificate[] chain,
                                         String authType) throws CertificateException {
                    return true;
                }
            }).build();
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext);
            this.httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyStoreException e) {
            e.printStackTrace();
        }
        this.httpclient = HttpClients.createDefault();




        //



    }


    public Map<String, Object> getByte(String url){



        HttpGet httpget= new HttpGet(url);



        Map<String, Object> responseBody = null;

        try {
            responseBody = this.httpclient.execute(httpget, this.responseByteHandler);
        }catch (ClientProtocolException e) {
            e.printStackTrace();
        }catch (UnknownHostException e){
            e.printStackTrace();
            System.out.println(url + "主机无法访问，请检查网络连接");
        }catch (IOException e){
            e.printStackTrace();
        }

        // httpclient没有返回数据，或者没有获取到指定位置没有获取到变量，用默认值填充
        if (responseBody == null){
            responseBody = new HashMap<String, Object>();
        }


        String html = null;
        try{
            html = new String((byte[])responseBody.get("byte"), "UTF-8");
        }catch (UnsupportedEncodingException e){
            e.printStackTrace();
        }


        String charset = null;
        Document document = Jsoup.parse(html);
        Elements elements = document.select("meta");
        for(Element metaElement : elements){
            if(metaElement!=null && metaElement.attr("http-equiv").toLowerCase().equals("content-type")){
                String content = metaElement.attr("content");
                String regex = ".*charset=([^;]*).*";
                Pattern pattern = Pattern.compile(regex);
                Matcher matcher = pattern.matcher(content);
                if(matcher.find())
                    charset = matcher.group(1);
                break;
            }
        }

        if (charset != null){
            responseBody.put("charset", charset);
        }


        Pattern pattern = Pattern.compile("(http|https)://(.+?)/");
        Matcher matcher = pattern.matcher(url + '/');

        StringBuffer domain = new StringBuffer();

        if(matcher.find()){
            domain.append(matcher.group(1)).append("://").append(matcher.group(2));
        }

        responseBody.put("domain", domain.toString());





        if (responseBody.get("contentType") == null){
            responseBody.put("contentType", MediaType.MULTIPART_FORM_DATA_VALUE);  //  text/html; charset=GB2312
        }
        if(responseBody.get("byte") == null){
            responseBody.put("byte", 0);
        }
        if (responseBody.get("charset") == null){
            responseBody.put("charset", "UTF-8");  // charset=GB2312
        }
        if (responseBody.get("type") == null){
            responseBody.put("type", MediaType.MULTIPART_FORM_DATA_VALUE);   //  text/html
        }
        return responseBody;

    }


}
